/**
 * 类型为n的字段处理
 * 数字类型的处理
 * 组装时若无长度指示则为右靠左补0
 */
package cc.rengu.igas.channel.cups.common.util;

import cc.rengu.igas.channel.cups.common.constant.CupsParamConstant;
import cc.rengu.jradp.exception.SystemException;
import cc.rengu.jradp.mods.trmsg.iso8583.FieldFactory;
import cc.rengu.jradp.mods.trmsg.iso8583.IsoTypeFactory;
import cc.rengu.jradp.mods.trmsg.iso8583.type.length.NonLengthTypeParseInfo;

import java.io.UnsupportedEncodingException;
import java.util.Arrays;
import java.util.Map;

/**
 * @author lizhangtao
 */
public class NumericFieldParseInfo extends IsoTypeFactory {
    private final static String BLANK = " ";

    /**
     * ASCII数字格式，无需decode
     *
     * @param buf    完整报文
     * @param pos    当前位置，当前字段解析的起始位置
     * @param fields 所有字段属性
     * @param index  当前字段在所有字段属性的index
     * @return 解析后赋值当前字段的属性及值
     */
    @Override
    public FieldFactory decode(byte[] buf, int pos, Map<String, FieldFactory> fields, String index) {
        if (pos < 0) {
            throw new SystemException("数字类型解析,位置非法pos=[" + pos + "]");
        } else if (pos + fields.get(index).getLength() > buf.length) {
            throw new SystemException("数字类型解析,位置非法pos=[" + pos + "] [" + fields.get(index).getLength() + "] > message length[" + buf.length + "]");
        } else {
            String value;
            try {
                //纯数字，所以使用什么字符集都可以
                value = new String(buf, pos, fields.get(index).getLength(), CupsParamConstant.GB18030);
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
                throw new SystemException("不支持的编码格式" + CupsParamConstant.GB18030);
            }
            byte[] dest = new byte[fields.get(index).getLength()];
            System.arraycopy(buf, pos, dest, 0, fields.get(index).getLength());
            fields.get(index).setOrgValue(dest);
            fields.get(index).setValue(value);
            return fields.get(index);
        }
    }

    /**
     * 检查是否为数字0-9
     *
     * @param buf    完整报文
     * @param pos    当前位置，当前字段解析的起始位置
     * @param fields 所有字段属性
     * @param index  当前字段在所有字段属性的index
     * @return true检查通过，false检查失败
     */
    @Override
    public boolean check(byte[] buf, int pos, Map<String, FieldFactory> fields, String index) {
        if (pos < 0) {
            return false;
        } else if (pos + fields.get(index).getLength() > buf.length) {
            return false;
        }

        for (int i = 0; i < fields.get(index).getLength(); i++) {
            if (buf[pos + i] < 48) {
                return false;
            } else if (buf[pos + i] > 57) {
                return false;
            }
        }
        return true;
    }

    /**
     * 组装该字段
     *
     * @param fields 所有字段属性集合
     * @param index  当前字段在所有字段集合的index
     * @return true检查通过，false检查失败
     */
    @Override
    public FieldFactory encode(Map<String, FieldFactory> fields, String index) {
        FieldFactory field = fields.get(index);
        if (field == null) {
            return null;
        }
        if (BLANK.equals(field.getValue())) {
            field.setValue("0");
        }
        if (field.getLenType() instanceof NonLengthTypeParseInfo) {
            byte[] byteTmp = new byte[field.getLength() + 1];
            Arrays.fill(byteTmp, (byte) '0');
            //纯数字，所以使用什么字符集都可以
            byte[] valueByte;
            try {
                valueByte = field.getValue().getBytes(CupsParamConstant.GB18030);
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
                throw new SystemException("不支持的编码格式" + CupsParamConstant.GB18030);
            }
            int lenTmp1 = field.getLength();
            int lenTmp2 = lenTmp1 - valueByte.length;
            int valueLen = valueByte.length;
            System.arraycopy(valueByte, 0, byteTmp, lenTmp2, valueLen);
            byteTmp[lenTmp1] = ' ';
            field.setOrgValue(byteTmp);

        } else {
            byte[] byteTmp = null;
            if (field.getValue() != null) {
                //纯数字，所以使用什么字符集都可以
                try {
                    byteTmp = field.getValue().getBytes(CupsParamConstant.GB18030);
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                    throw new SystemException("不支持的编码格式" + CupsParamConstant.GB18030);
                }
            }
            if (byteTmp == null) {
                return null;
            }
            field.setLength(byteTmp.length);
            byte[] out = new byte[byteTmp.length + 1];
            System.arraycopy(byteTmp, 0, out, 0, byteTmp.length);
            out[byteTmp.length] = 32;
            //纯数字，所以使用什么字符集都可以
            String tmp = null;
            try {
                tmp = new String(out, CupsParamConstant.GB18030);
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
                throw new SystemException("不支持的编码格式" + CupsParamConstant.GB18030);
            }
            field.setValue(tmp);
            field.setOrgValue(out);
        }

        return field;
    }
}
